package com.streamApi;

import javax.security.auth.login.LoginException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class StreamTest {



    public static void main(String[] args) throws LoginException {
        //泛型
        List<? super String> a = new ArrayList<>();
        a.add(null); a.add("String");
        List<? extends String> b = new ArrayList<>();
        b.add(null);
        // 会报错 list.add("String");

        List<Person> personList = new ArrayList<Person>();
        personList.add(new Person("张三", 8, 3000));
        personList.add(new Person("李四", 18, 5000));
        personList.add(new Person("王五", 28, 7000));
        personList.add(new Person("孙六", 38, 9000));
//        List<String> list = init() ;
//// 创建一个顺序流
//        System.out.println("窜行===="+new Date().getTime());
//        list.stream().forEach(item->{
//            System.out.println(Thread.currentThread().getName());
//        });
//        System.out.println("窜行===="+new Date().getTime());
//        System.out.println("并行===="+new Date().getTime());
//        list.parallelStream().forEach(item->{
//            System.out.println(Thread.currentThread().getName());
//        });
//        System.out.println("并行===="+new Date().getTime());
//        //1、遍历/匹配（foreach/find/match）
//        List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
//
//        // 遍历输出符合条件的元素
//        list.stream().filter(x -> x > 6).forEach(System.out::println);
//        // 匹配第一个
//        Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
//        // 匹配任意（适用于并行流）
//        Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();
//        // 是否包含符合特定条件的元素
//        boolean anyMatch = list.stream().anyMatch(x -> x < 6);
//        System.out.println("匹配第一个值：" + findFirst.get());
//        System.out.println("匹配任意一个值：" + findAny.get());
//        System.out.println("是否存在大于6的值：" + anyMatch);

        //2、按条件匹配   filter  属性attributes
//        List<Person> collect = personList.stream().filter(x -> x.getAge()>=18).collect(Collectors.toList());

//        //3、聚合    max、min、count
//        List<String> list = Arrays.asList("zhangsan", "lisi", "wangwu", "sunliu");
//        Comparator<? super String> comparator = Comparator.comparing(String::length);
//        Optional<String> max = list.stream().max(comparator);
//        List<Integer> list2 = Arrays.asList(1, 17, 27, 7);
//        Optional<Integer> max2 = list2.stream().max(Integer::compareTo);
//        long count = list.stream().count();
//        System.out.println(count);
//        System.out.println(max.get());
//        System.out.println(max2.get());

          //4、map与flatMap  attr
        //map接收一个函数作为参数，该函数会被应用到每个元素上，并将其映射成一个新的元素。
        //flatMap 接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流。
//        List<Integer> list = Arrays.asList(1, 17, 27, 7);
//        List<Integer> collect = list.stream().map(x -> x + 3).collect(Collectors.toList());
//        System.out.println(collect);

//        String[] arr = {"z, h, a, n, g", "s, a, n"};
//        List<String> list = Arrays.asList(arr);
//        System.out.println(list);
//        List<String> collect = list.stream().flatMap(x -> {
//            String[] array = x.split(",");
//            Stream<String> stream = Arrays.stream(array);
//            return stream;
//        }).collect(Collectors.toList());
//        System.out.println(collect);

        //5、规约reduce 是把一个流缩减成一个值，能实现对集合求和、求乘积和求最值操作
        List<Integer> list = Arrays.asList(1, 2, 3, 4);

        //求和
        Optional<Integer> reduce = list.stream().reduce((x,y) -> x+ y);
        System.out.println("求和:"+reduce);
        //求积
        Optional<Integer> reduce2 = list.stream().reduce((x,y) -> x * y);
        System.out.println("求积:"+reduce2);
        //求最大值
        Optional<Integer> reduce3 = list.stream().reduce((x,y) -> x>y?x:y);
        System.out.println("求最大值:"+reduce3);
       //6、收集（toList、toSet、toMap）
//        Map<String, Person> collect = personList.stream().filter(x -> x.getAge() > 18).collect(Collectors.toMap(Person::getName, y -> y));
//        System.out.println(collect);

        //7、collect
//        计数： count
//
//        平均值： averagingInt、 averagingLong、 averagingDouble
//
//        最值： maxBy、 minBy
//
//        求和： summingInt、 summingLong、 summingDouble
//
//        统计以上所有： summarizingInt、 summarizingLong、 summarizingDouble
//统计员工人数
//        Long count = personList.stream().collect(Collectors.counting());
//        //求平均工资
//        Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
//        //求最高工资
//        Optional<Integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));
//        //求工资之和
//        Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary));
//        //一次性统计所有信息
//        DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));
//        System.out.println("统计员工人数:"+count);
//        System.out.println("求平均工资:"+average);
//        System.out.println("求最高工资:"+max);
//        System.out.println("求工资之和:"+sum);
//        System.out.println("一次性统计所有信息:"+collect);

        //8、分组(partitioningBy/groupingBy)
        //分区：将stream按条件分为两个 Map，比如员工按薪资是否高于8000分为两部分。

       // 分组：将集合分为多个Map，比如员工按性别分组。有单级分组和多级分组。
//
//        personList.add(new Person("zhangsan",25, 3000, "male", "tieling"));
//        personList.add(new Person("lisi",27, 5000, "male", "tieling"));
//        personList.add(new Person("wangwu",29, 7000, "female", "tieling"));
//        personList.add(new Person("sunliu",26, 3000, "female", "dalian"));
//        personList.add(new Person("yinqi",27, 5000, "male", "dalian"));
//        personList.add(new Person("guba",21, 7000, "female", "dalian"));
//
//        // 将员工按薪资是否高于8000分组
//        Map<Boolean, List<Person>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
//        // 将员工按性别分组
//        Map<String, List<Person>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));
//        // 将员工先按性别分组，再按地区分组
//        Map<String, Map<String, List<Person>>> group2 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
//        System.out.println("员工按薪资是否大于8000分组情况：" + part);
//        System.out.println("员工按性别分组情况：" + group);
//        System.out.println("员工按性别、地区：" + group2);

        //9、连接joining
//        String collect1 = personList.stream().map(Person::getName).collect(Collectors.joining(","));
//        System.out.println(collect1);

        //10、排序sorted
        // 按工资升序排序（自然排序）
//        List<String> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName)
//                .collect(Collectors.toList());
        // 按工资倒序排序
//        List<String> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
//                .map(Person::getName).collect(Collectors.toList());
//        // 先按工资再按年龄升序排序
//        List<String> newList3 = personList.stream()
//                .sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName)
//                .collect(Collectors.toList());
//        // 先按工资再按年龄自定义排序（降序）
//        List<String> newList4 = personList.stream().sorted((p1, p2) -> {
//            if (p1.getSalary() == p2.getSalary()) {
//                return p2.getAge() - p1.getAge();
//            } else {
//                return p2.getSalary() - p1.getSalary();
//            }
//        }).map(Person::getName).collect(Collectors.toList());
//
//        System.out.println("按工资升序排序：" + newList);
//        System.out.println("按工资降序排序：" + newList2);
//        System.out.println("先按工资再按年龄升序排序：" + newList3);
//        System.out.println("先按工资再按年龄自定义降序排序：" + newList4);
//        //11、提取/组合
//        String[] arr1 = { "a", "b", "c", "d" };
//        String[] arr2 = { "d", "e", "f", "g" };
//        Stream<String> stream1 = Stream.of(arr1);
//        Stream<String> stream2 = Stream.of(arr2);
//        // concat:合并两个流 distinct：去重
//        List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
//        // limit：限制从流中获得前n个数据
//        List<Integer> collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
//        // skip：跳过前n个数据
//        List<Integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());
//
//        System.out.println("流合并：" + newList);
//        System.out.println("limit：" + collect);
//        System.out.println("skip：" + collect2);
        //13、计算两个list中的差集
        //计算两个list中的差集
//        List<String> reduce1 = allList.stream().filter(item -> !wList.contains(item)).collect(Collectors.toList());



    }
    public static List<String> init(){
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            list.add("aaa"+i);
        }
        return list;
    }
}
